﻿using System;
using System.Diagnostics;
using System.Net;
using System.Threading.Tasks;
using WxLib.Core.Exceptions;
using WxLib.Core.Serializers;
using WxLib.Core.Util;

namespace WxLib.Core.RequestHandlers
{
    /// <summary>
    ///     A basic RequestHandler with no special handling.
    /// </summary>
    public class RequestHandler : IPostRequestHandler
    {
        private readonly TraceSource _trace = new TraceSource("WxLib", SourceLevels.All);

        /// <summary>
        ///  构造函数
        /// </summary>
        /// <param name="serializer">序列化器用于反序列化</param>
        public RequestHandler(ISerializer serializer)
        {
            Serializer = serializer;
        }

        /// <summary>
        ///  获取或设置用于反序列化响应数据的ISerializer
        /// </summary>
        public ISerializer Serializer { get; set; }

        /// <summary>
        /// 对指定的URI执行GET请求，并返回反序列化的数据。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="uri"></param>
        /// <returns></returns>
        public virtual async Task<T> RequestAsync<T>(Uri uri)
        {
            _trace.TraceEvent(TraceEventType.Verbose, 0, "RequestHandler.Deserialize:Start");
            string data;
            try
            {
                data = await HttpRequestHelper.RequestAsync(uri).ConfigureAwait(false);
            }
            catch (WebException e)
            {
                throw new WxLibWebException("A request caused a WebException.", e.InnerException as WebException);
            }
            var val = Serializer.Deserialize<T>(data);
            _trace.TraceEvent(TraceEventType.Verbose, 0, "RequestHandler.Deserialize:Complete");
            return val;
        }

        /// <summary>
        /// 对指定的URI执行POST请求，并返回反序列化的数据。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="uri"></param>
        /// <param name="postData"></param>
        /// <returns></returns>
        public async Task<T> PostRequestAsync<T>(Uri uri, string postData)
        {
            _trace.TraceEvent(TraceEventType.Verbose, 0, "RequestHandler.Deserialize:Start");
            string data;
            try
            {
                data = await HttpRequestHelper.PostRequestAsync(uri, postData).ConfigureAwait(false);
            }
            catch (WebException e)
            {
                throw new WxLibWebException("A request caused a WebException.", e.InnerException as WebException);
            }
            var val = Serializer.Deserialize<T>(data);
            _trace.TraceEvent(TraceEventType.Verbose, 0, "RequestHandler.Deserialize:Complete");
            return val;
        }


       



        public async Task<T> PostRequestAsync<T>(Uri uri, byte[] postData)
        {
            _trace.TraceEvent(TraceEventType.Verbose, 0, "RequestHandler.Deserialize:Start");
            string data;
            try
            {
                data = await HttpRequestHelper.PostRequestAsync(uri, postData).ConfigureAwait(false);
            }
            catch (WebException e)
            {
                throw new WxLibWebException("A request caused a WebException.", e.InnerException as WebException);
            }
            var val = Serializer.Deserialize<T>(data);
            _trace.TraceEvent(TraceEventType.Verbose, 0, "RequestHandler.Deserialize:Complete");
            return val;
        }


        /// <summary>
        /// 对指定的URI执行POST并带证书请求，并返回反序列化的数据。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="uri"></param>
        /// <param name="postData"></param>
        /// <param name="certPath"></param>
        /// <param name="certPassword"></param>
        /// <returns></returns>
        public async Task<T> PostRequestAsync<T>(Uri uri, string postData, string certPath, string certPassword)
        {
            _trace.TraceEvent(TraceEventType.Verbose, 0, "RequestHandler.Deserialize:Start");
            string data;
            try
            {
                data = await HttpRequestHelper.PostRequestAsync(uri, postData, certPath, certPassword).ConfigureAwait(false);
            }
            catch (WebException e)
            {
                throw new WxLibWebException("A request caused a WebException.", e.InnerException as WebException);
            }
            var val = Serializer.Deserialize<T>(data);
            _trace.TraceEvent(TraceEventType.Verbose, 0, "RequestHandler.Deserialize:Complete");
            return val;
        }
    }
}